package com.gpframework.module.controller.order;

import cn.hutool.http.HttpRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import java.io.IOException;
import java.util.*;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import com.gpframework.common.config.GpframeworkConfig;
import com.gpframework.common.core.domain.entity.SysUser;
import com.gpframework.common.enums.OrderStatusEnum;
import com.gpframework.common.enums.YesNoEnum;
import com.gpframework.common.utils.DateUtils;
import com.gpframework.common.utils.StringUtils;
import com.gpframework.common.utils.poi.ExcelExporter;
import com.gpframework.module.order.domain.GpDestinationNoConfig;
import com.gpframework.module.order.domain.vo.*;
import com.gpframework.module.system.mapper.SysUserMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.gpframework.common.annotation.Log;
import com.gpframework.common.core.controller.BaseController;
import com.gpframework.common.core.domain.AjaxResult;
import com.gpframework.common.enums.BusinessType;
import com.gpframework.module.order.domain.GpOrderFlow;
import com.gpframework.module.order.domain.req.GpOrderFlowReq;
import com.gpframework.module.order.domain.req.GpOrderFlowAdd;
import com.gpframework.module.order.domain.req.GpOrderFlowUpdate;
import com.gpframework.module.order.service.IGpOrderFlowService;
import com.gpframework.common.utils.poi.ExcelUtil;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import io.swagger.annotations.*;
import com.gpframework.common.core.page.TableDataInfo;
/**
 * @ClassName GpOrderFlowController
 * @Author gpframework
 * @Date 2023-06-16
 * @Version 1.0.0
 * @Description 员工订单流转详情Controller
 */
@Validated
@Api(tags = "员工订单流转详情")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@RestController
@SuppressWarnings({"rawtypes","unchecked"})
@RequestMapping("/order/orderFlow" )
public class GpOrderFlowController extends BaseController {

    private final IGpOrderFlowService iGpOrderFlowService;
    private final SysUserMapper sysUserMapper;

 /**
  * @Description 分页
  * @Author gpframework
  * @Date 2023-06-16
  * @Param gpOrderFlow
  * @Return TableDataInfo
 */
    @ApiOperation("列表")
    @PreAuthorize("@ss.hasPermi('order:orderFlow:list')")
    @GetMapping("/list")
    public TableDataInfo<GpOrderFlowVo> list(GpOrderFlowReq gpOrderFlowReq)
    {
        startPage();
        QueryWrapper<GpOrderFlow> lqw = new QueryWrapper<GpOrderFlow>();
        gpOrderFlowReq.generatorQuery(lqw,true);
        lqw.eq("o.del_status", YesNoEnum.NO.getKey());
        lqw.groupBy("gp.order_id", "gp.user_id");
        List<GpOrderFlowVo> list = iGpOrderFlowService.listVo(lqw);
        return getDataTable(list);
    }

    /**
     * @Description 新增
     * @Author gpframework
     * @Date 2023-06-16
     * @Param gpOrderFlow
     * @Return TableDataInfo
     */
    @ApiOperation("新增")
    @PreAuthorize("@ss.hasPermi('order:orderFlow:add')" )
    @Log(title = "添加员工订单流转详情" , businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Valid @RequestBody GpOrderFlowAdd gpOrderFlowAdd) {
        GpOrderFlow gpOrderFlow = Convert.convert(new TypeReference<GpOrderFlow>() {}, gpOrderFlowAdd);
        return toAjax(iGpOrderFlowService.save(gpOrderFlow) ? 1 : 0);
    }

    /**
     * @Description 修改
     * @Author gpframework
     * @Date 2023-06-16
     * @Param gpOrderFlow
     * @Return TableDataInfo
     */
    @ApiOperation("修改")
    @PreAuthorize("@ss.hasPermi('order:orderFlow:edit')" )
    @Log(title = "修改员工订单流转详情" , businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Valid @RequestBody GpOrderFlowUpdate gpOrderFlowUpdate) {
        GpOrderFlow gpOrderFlow = Convert.convert(new TypeReference<GpOrderFlow>() {}, gpOrderFlowUpdate);
        return toAjax(iGpOrderFlowService.updateById(gpOrderFlow) ? 1 : 0);
    }


    /**
     * @Description 导出
     * @Author gpframework
     * @Date 2023-06-16
     * @Param gpOrderFlow
     * @Return TableDataInfo
     */

    @PreAuthorize("@ss.hasPermi('order:orderFlow:export')" )
    @Log(title = "导出员工订单流转详情" , businessType = BusinessType.EXPORT)
    @GetMapping("/export" )
    public AjaxResult export(GpOrderFlowReq gpOrderFlowReq) {
        QueryWrapper<GpOrderFlow> lqw = new QueryWrapper<GpOrderFlow>();
        gpOrderFlowReq.generatorQuery(lqw,true);
        List<GpOrderFlowVo> list = iGpOrderFlowService.listVo(lqw);
        ExcelUtil<GpOrderFlowVo> util = new ExcelUtil<GpOrderFlowVo>(GpOrderFlowVo. class);
        return util.exportExcel(list, "orderFlow" );
    }

    /**
     * @Description 详情
     * @Author gpframework
     * @Date 2023-06-16
     * @Param gpOrderFlow
     * @Return TableDataInfo
     */
    @ApiOperation("详情")
    @PreAuthorize("@ss.hasPermi('order:orderFlow:query')" )
    @GetMapping(value = "/{id}" )
    public AjaxResult<GpOrderFlowVo> getInfo(@PathVariable("id" ) Long id) {
        return AjaxResult.success(iGpOrderFlowService.getVoById(id));
    }



    /**
     * @Description 删除
     * @Author gpframework
     * @Date 2023-06-16
     * @Param gpOrderFlow
     * @Return TableDataInfo
     */
    @ApiOperation("删除")
    @PreAuthorize("@ss.hasPermi('order:orderFlow:remove')" )
    @Log(title = "删除员工订单流转详情" , businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}" )
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(iGpOrderFlowService.removeByIds(Arrays.asList(ids)) ? 1 : 0);
    }

    /**
     * @Description 确认
     * @Author gpframework
     * @Date 2023-06-16
     * @Param gpOrder
     * @Return AjaxResult
     */
    @ApiOperation("确认")
    @PreAuthorize("@ss.hasPermi('order:orderFlow:edit')" )
    @PostMapping("/confirm")
    public AjaxResult confirm(@Valid @RequestBody GpOrderFlowUpdate gpOrderFlowUpdate) {
        if (gpOrderFlowUpdate.getUserId() == null || gpOrderFlowUpdate.getConfigId() == null || gpOrderFlowUpdate.getId() == null || gpOrderFlowUpdate.getProcessingTime() == null) {
            return AjaxResult.error("缺少必要参数[id]|[userId]|[configId]|[processingTime]");
        }
        return iGpOrderFlowService.add(gpOrderFlowUpdate);
    }

    /**
     * @Description 拿货时长统计表
     * @Author gpframework
     * @Date 2023-06-16
     * @Param gpOrderFlow
     * @Return TableDataInfo
     */
    @ApiOperation("拿货时长统计表")
    @PreAuthorize("@ss.hasPermi('order:report:list')" )
    @GetMapping(value = "/forms" )
    public AjaxResult forms(HttpServletRequest request) {
        String userId = request.getParameter("userId");
        String deptId = request.getParameter("deptId");
        String type = request.getParameter("type");
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        String organiseUnit = request.getParameter("organiseUnit");
        if ((StringUtils.isBlank(userId) && StringUtils.isBlank(deptId))|| StringUtils.isBlank(type)) {
            return AjaxResult.error("缺少必要参数");
        }
        return AjaxResult.success(iGpOrderFlowService.forms(userId, deptId, type, organiseUnit, startTime, endTime));
    }

    /**
     * @Description 时效报表
     * @Author gpframework
     * @Date 2023-06-16
     * @Param gpOrderFlow
     * @Return TableDataInfo
     */
    @ApiOperation("时效报表")
    @GetMapping(value = "/efficiency" )
    public AjaxResult efficiency(HttpServletRequest request) {
        String deptId = request.getParameter("deptId");
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        return AjaxResult.success(iGpOrderFlowService.efficiency(deptId, startTime, endTime));
    }

    /**
     * @Description 时效报表（小程序使用）
     * @Author gpframework
     * @Date 2023-06-16
     * @Param gpOrderFlow
     * @Return TableDataInfo
     */
    @ApiOperation("时效报表（小程序使用）")
    @GetMapping(value = "/efficiencyApplet" )
    public AjaxResult efficiencyApplet(HttpServletRequest request) {
        String deptId = "0";
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        return AjaxResult.success(iGpOrderFlowService.efficiency(deptId, startTime, endTime));
    }

    /**
     * @Description 单量统计表
     * @Author gpframework
     * @Date 2023-06-16
     * @Param gpOrderFlow
     * @Return TableDataInfo
     */
    @ApiOperation("单量统计表")
    @GetMapping(value = "/orderQuantityStatistics" )
    public AjaxResult orderQuantityStatistics(HttpServletRequest request) {
        String deptId = request.getParameter("deptId");
        String type = request.getParameter("type");
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        if (StringUtils.isBlank(type)) {
            return AjaxResult.error("请选择查询组别");
        }
        if (StringUtils.isBlank(startTime) || StringUtils.isBlank(endTime)) {
            return AjaxResult.error("请选择查询时间段");
        }
        SysUser sysUser = new SysUser();
        sysUser.setDeptId(Long.valueOf(deptId));
//        startPage();
        String orderStatus = null;
        if (StringUtils.equals(type, "拿货")) {
            orderStatus = OrderStatusEnum.TO_BE_STOCK_UP.getKey();
        }else if (StringUtils.equals(type, "备货")) {
            orderStatus = OrderStatusEnum.TO_BE_SEND_OUT_GOODS.getKey();
        }else if (StringUtils.equals(type, "仓库发货")) {
            orderStatus = OrderStatusEnum.TO_BE_TRANSFER.getKey();
        }else if (StringUtils.equals(type, "中转发货")) {
            orderStatus = OrderStatusEnum.COMPLETE.getKey();
        }
        List<SysUser> sysUsers = iGpOrderFlowService.selectUserList(deptId, orderStatus, startTime, endTime);
        return AjaxResult.success(iGpOrderFlowService.orderQuantityStatistics(deptId, sysUsers, orderStatus, startTime, endTime));
    }

    /**
     * @Description 单量统计表（小程序使用）
     * @Author gpframework
     * @Date 2023-06-16
     * @Param gpOrderFlow
     * @Return TableDataInfo
     */
    @ApiOperation("单量统计表（小程序使用）")
    @GetMapping(value = "/orderQuantityStatisticsApplet" )
    public AjaxResult orderQuantityStatisticsApplet(HttpServletRequest request) {
        String deptId = "0";
        String type = request.getParameter("type");
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        if (StringUtils.isBlank(type)) {
            return AjaxResult.error("请选择查询组别");
        }
        if (StringUtils.isBlank(startTime) || StringUtils.isBlank(endTime)) {
            return AjaxResult.error("请选择查询时间段");
        }
        SysUser sysUser = new SysUser();
        sysUser.setDeptId(Long.valueOf(deptId));
//        startPage();
        String orderStatus = null;
        if (StringUtils.equals(type, "拿货")) {
            orderStatus = OrderStatusEnum.TO_BE_STOCK_UP.getKey();
        }else if (StringUtils.equals(type, "备货")) {
            orderStatus = OrderStatusEnum.TO_BE_SEND_OUT_GOODS.getKey();
        }else if (StringUtils.equals(type, "发货")) {
            orderStatus = OrderStatusEnum.TO_BE_TRANSFER.getKey();
        }
        List<SysUser> sysUsers = iGpOrderFlowService.selectUserList(deptId, orderStatus, startTime, endTime);
        return AjaxResult.success(iGpOrderFlowService.orderQuantityStatistics(deptId, sysUsers, orderStatus, startTime, endTime));
    }

    /**
     * @Description 单量统计表
     * @Author gpframework
     * @Date 2023-06-16
     * @Param gpOrderFlow
     * @Return TableDataInfo
     */
    @ApiOperation("单量统计表导出")
    @GetMapping(value = "/orderQuantityStatistics/export" )
    public AjaxResult orderQuantityStatisticsExport(HttpServletRequest request) throws IOException {
        String deptId = request.getParameter("deptId");
        String type = request.getParameter("type");
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        if (StringUtils.isBlank(type)) {
            return AjaxResult.error("请选择查询组别");
        }
        if (StringUtils.isBlank(startTime) || StringUtils.isBlank(endTime)) {
            return AjaxResult.error("请选择查询时间段");
        }
        SysUser sysUser = new SysUser();
        sysUser.setDeptId(Long.valueOf(deptId));
//        startPage();
        String orderStatus = null;
        if (StringUtils.equals(type, "拿货")) {
            orderStatus = OrderStatusEnum.TO_BE_STOCK_UP.getKey();
        }else if (StringUtils.equals(type, "备货")) {
            orderStatus = OrderStatusEnum.TO_BE_SEND_OUT_GOODS.getKey();
        }else if (StringUtils.equals(type, "发货")) {
            orderStatus = OrderStatusEnum.TO_BE_TRANSFER.getKey();
        }
        List<SysUser> sysUsers = iGpOrderFlowService.selectUserList(deptId, orderStatus, startTime, endTime);
        List<OrderQuantityVo> list = iGpOrderFlowService.orderQuantityStatistics(deptId, sysUsers, orderStatus, startTime, endTime);
        List<String> headers = new ArrayList<>();
        headers.add("姓名");
        for (OrderQuantityDayVo orderQuantityDayVo : list.get(0).getOrderQuantityDayList()) {
            headers.add(orderQuantityDayVo.getOrderDate());
        }
        headers.add("总完成单量");
        headers.add("出勤天数");
        headers.add("平均每天/单");
        List<Map<String, Object>> data = new ArrayList<>();
        Map<String, Object> map;
        for (OrderQuantityVo orderQuantityVo : list) {
            map = new HashMap<>();
            map.put("姓名", orderQuantityVo.getUserName());
            map.put("总完成单量", orderQuantityVo.getTotalCompleteOrderNum().toString());
            map.put("出勤天数", orderQuantityVo.getAttendanceDays().toString());
            map.put("平均每天/单", orderQuantityVo.getDailyCompletedOrdersAvg().toString());
            for (OrderQuantityDayVo orderQuantityDayVo : orderQuantityVo.getOrderQuantityDayList()) {
                map.put(orderQuantityDayVo.getOrderDate(), orderQuantityDayVo.getOrderNum().toString());
            }
            data.add(map);
        }
        String fileName = UUID.randomUUID() + "单量统计表.xlsx";
        String filePath = GpframeworkConfig.getDownloadPath() + fileName;
        ExcelExporter.exportExcel(filePath, headers, data);
        return AjaxResult.success("导出成功",fileName);
    }
}
